package com.paishen.peiniwan.module.date;

import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Build;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.paishen.common.dialog.LoadingDialog;
import com.paishen.common.util.BaseUtil;
import com.paishen.common.util.DateUtil;
import com.paishen.peiniwan.App;
import com.paishen.peiniwan.BaseActivity;
import com.paishen.peiniwan.BusEvent;
import com.paishen.peiniwan.C;
import com.paishen.peiniwan.R;
import com.paishen.peiniwan.database.util.ModelConverter;
import com.paishen.peiniwan.frame.PnwOkCallbackAdapter;
import com.paishen.peiniwan.frame.http.HttpResp;
import com.paishen.peiniwan.frame.http.PnwHttpManager;
import com.paishen.peiniwan.frame.http.entity.DatePull;
import com.paishen.peiniwan.frame.http.response.HttpRespData;
import com.paishen.common.widget.MaterialHeader;
import com.paishen.peiniwan.module.profile.ProfileInfoActivity;
import com.squareup.okhttp.Request;

import java.util.ArrayList;
import java.util.List;

import de.greenrobot.event.EventBus;
import in.srain.cube.views.ptr.PtrDefaultHandler;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrHandler;

public class MainDateLayout extends FrameLayout {
    private View layEmpty;

    private final PtrFrameLayout layPtrFrame;
    private final RecyclerView viewRecycler;
    private final DatePullAdapter adapter;
    private final LinearLayoutManager layoutManager;

    private boolean reqLoad = false;
    private boolean fetchOver = false;
    private int currPage = 1;

    public MainDateLayout(Context context) {
        this(context, null);
    }

    public MainDateLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.layout_main_date, this);
        setPadding(0, (int) getResources().getDimension(R.dimen.title_height) + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? BaseUtil.getStatusBarHeight() : 0), 0, 0);

        viewRecycler = (RecyclerView) findViewById(R.id.view_recycler);
        viewRecycler.setLayoutManager(layoutManager = new LinearLayoutManager(getContext()));
        viewRecycler.setAdapter(adapter = new DatePullAdapter());
        viewRecycler.setItemAnimator(new DefaultItemAnimator());
        viewRecycler.addItemDecoration(new RecyclerView.ItemDecoration() {
            int spacing = BaseUtil.dip2px(10);

            @Override
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                outRect.top = spacing;
            }
        });
        viewRecycler.addOnScrollListener(new RecyclerView.OnScrollListener() {
            private boolean scrollDown = false;

            @Override
            public void onScrolled(RecyclerView viewRecycler, int dx, int dy) {
                super.onScrolled(viewRecycler, dx, dy);
                scrollDown = dy > 0;
            }

            @Override
            public void onScrollStateChanged(RecyclerView viewRecycler, int newState) {
                super.onScrollStateChanged(viewRecycler, newState);
                switch (newState) {
                    case RecyclerView.SCROLL_STATE_IDLE:
                        int lastVisibleItem = layoutManager.findLastCompletelyVisibleItemPosition();
                        int totalItemCount = layoutManager.getItemCount();
                        if (lastVisibleItem >= (totalItemCount - 1) && scrollDown) {
                            if (!fetchOver) requestOrderGetBookPending();
                        }

                        break;
                    case RecyclerView.SCROLL_STATE_DRAGGING:
                        break;
                }
            }
        });

        layPtrFrame = (PtrFrameLayout) findViewById(R.id.lay_ptr_frame);
        MaterialHeader header = new MaterialHeader(getContext());
        int[] colors = new int[]{0xFF05131A};
        header.setColorSchemeColors(colors);
        header.setLayoutParams(new PtrFrameLayout.LayoutParams(-1, -2));
        header.setPadding(0, BaseUtil.dip2px(15), 0, BaseUtil.dip2px(10));
        header.setPtrFrameLayout(layPtrFrame);
        layPtrFrame.setDurationToCloseHeader(1500);
        layPtrFrame.setHeaderView(header);
        layPtrFrame.addPtrUIHandler(header);
        layPtrFrame.setPtrHandler(new PtrHandler() {
            @Override
            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {
                return PtrDefaultHandler.checkContentCanBePulledDown(frame, viewRecycler, header);
            }

            @Override
            public void onRefreshBegin(final PtrFrameLayout frame) {
                currPage = 1;
                requestOrderGetBookPending();
            }
        });

        layEmpty = findViewById(R.id.lay_empty);

        requestOrderGetBookPending();
    }


    public void requestOrderGetBookPending() {
        final int page = currPage;

        if (reqLoad) return;
        reqLoad = true;

        adapter.refreshLoadState(true);
        PnwHttpManager.Order.getBookPending(((BaseActivity) getContext()).TAG, page, new PnwOkCallbackAdapter<HttpRespData<List<DatePull>>>() {
            @Override
            public void onResponse(HttpRespData<List<DatePull>> response, boolean fresh) {
                super.onResponse(response, fresh);
                layPtrFrame.refreshComplete();
                reqLoad = false;
                fetchOver = false;

                if (response.errcode == C.http.RESULT_SUCCESS) {

                    if (response.data != null && response.data.size() > 0) {
                        layEmpty.setVisibility(View.GONE);
                        fetchOver = response.data.size() < DatePullAdapter.FETCH_COUNT;
                        if (!fetchOver) currPage = currPage + 1;
                        boolean b = page != 1 ? adapter.append(response.data, fetchOver) : adapter.set(response.data, fetchOver);
                    } else {
                        boolean dateEmpty = (page == 1);
                        layEmpty.setVisibility(dateEmpty ? View.VISIBLE : View.GONE);
                        if (page != 1) BaseUtil.showToast(response.errmsg);

                        if (page == 1) {
                            EventBus.getDefault().post(new BusEvent(BusEvent.ACTION_REFRESH_MAIN_DATE_EMPTY));
                        }

                        fetchOver = true;
                        boolean b = page != 1 ? adapter.refreshLoadState(false) : adapter.set(new ArrayList<DatePull>(), true);
                    }
                } else if (fresh && response.errcode != C.http.RESULT_LOGIN_EXPIRE &&
                        response.errcode != C.http.RESULT_LOGIN_OFFLINE) {
                    layEmpty.setVisibility(View.VISIBLE);

                    EventBus.getDefault().post(new BusEvent(BusEvent.ACTION_REFRESH_MAIN_DATE_EMPTY));
                    // BaseUtil.showToast(response.errmsg);
                    adapter.refreshLoadState(false);
                }
            }

            @Override
            public void onFailure(Request request, Exception e) {
                super.onFailure(request, e);
                layPtrFrame.refreshComplete();
                reqLoad = false;
                adapter.refreshLoadState(false);
            }
        });
    }

    private static final class DatePullAdapter extends RecyclerView.Adapter<DatePullAdapter.ViewHolder> {
        public static final int FETCH_COUNT = 5;

        private final ViewGroup.MarginLayoutParams lpSubject;
        private final ViewGroup.MarginLayoutParams lpResponderHead;
        private final int d5;

        private AlertDialog dlgDatePull;
        private DateGiftChooseDialog dlgDateGiftChoose;

        static class DatePullElement {
            public static final int TYPE_ITEM = 1;
            public static final int TYPE_LOAD = 2;
            public int type;
            public Object element;
        }

        private final List<DatePullElement> datePullElements = new ArrayList<>();
        private final DatePullElement deLoad;

        DatePullAdapter() {
            d5 = BaseUtil.dip2px(5);
            lpSubject = new ViewGroup.MarginLayoutParams(BaseUtil.dip2px(65), BaseUtil.dip2px(25));
            lpSubject.setMargins(0, 0, d5, d5);
            lpResponderHead = new ViewGroup.MarginLayoutParams(d5 * 6, d5 * 6);
            lpResponderHead.setMargins(0, 0, d5, 0);

            deLoad = new DatePullElement();
            deLoad.element = true;
            deLoad.type = DatePullElement.TYPE_LOAD;
        }


        public boolean set(List<DatePull> dataList, boolean fetchOver) {
            if (dataList != null) {
                datePullElements.clear();
                for (DatePull data : dataList) {
                    DatePullElement de = new DatePullElement();
                    de.type = DatePullElement.TYPE_ITEM;
                    de.element = data;
                    datePullElements.add(de);
                }
                if (!fetchOver) {
                    datePullElements.add(deLoad);
                }
                notifyDataSetChanged();
                return true;
            }
            return false;
        }

        public boolean append(List<DatePull> dataList, boolean fetchOver) {
            if (dataList != null) {
                int loadIdx = datePullElements.indexOf(deLoad);
                if (loadIdx >= 0) {
                    datePullElements.remove(loadIdx);
                    notifyItemRemoved(loadIdx);
                }

                for (DatePull data : dataList) {
                    DatePullElement de = new DatePullElement();
                    de.type = DatePullElement.TYPE_ITEM;
                    de.element = data;
                    datePullElements.add(de);
                }

                if (!fetchOver) datePullElements.add(deLoad);
                notifyItemRangeInserted(loadIdx, dataList.size() + 1);
                return true;
            }
            return false;
        }

        public boolean refreshLoadState(boolean shown) {
            if (datePullElements.size() > 0) {
                deLoad.element = shown;
                int loadIdx = datePullElements.indexOf(deLoad);
                if (loadIdx >= 0) {
                    notifyItemChanged(loadIdx);
                }
                return true;
            }
            return false;
        }

        private void showDateGiftChooseDialog(final ViewHolderItem vhItem) {
            if (dlgDateGiftChoose == null) {
                dlgDateGiftChoose = new DateGiftChooseDialog.Builder(vhItem.itemView.getContext()).setOnGiftSelectedListener(new DateGiftChooseDialog.OnGiftSelectedListener() {
                    @Override
                    public void onGiftSelected(long giftId, float giftPrice) {
                        requestOrderBook(vhItem, vhItem.itemData.id, giftId);
                    }
                }).create();
            }
            dlgDateGiftChoose.show();
        }

        public class ViewHolder extends RecyclerView.ViewHolder {
            public ViewHolder(View view) {
                super(view);
            }
        }

        public class ViewHolderLoad extends ViewHolder {
            public ViewHolderLoad(View view) {
                super(view);
            }
        }

        public class ViewHolderItem extends ViewHolder implements OnClickListener {
            public ViewHolderItem(View view) {
                super(view);
            }

            @Override
            public void onClick(View v) {
                if (itemData.gift == null) {
                    showDateGiftChooseDialog(ViewHolderItem.this);
                } else {
                    requestOrderBook(this, itemData.id, -1);
                }
            }

            private View layGift;
            private ImageView imgGift;
            private TextView txGiftValue;

            private int position;
            private DatePull itemData;
            private ViewGroup laySubject, layResponder, layResponderHead;
            private TextView txNickname, txTime, txLocation, txEmptyResponder, txResponderCount;
            private Button btnUp;
            private ImageView imgAvatar;
            private View layAvatar;
        }

        @Override
        public int getItemCount() {
            return datePullElements.size();
        }

        @Override
        public int getItemViewType(int position) {
            return datePullElements.get(position).type;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
            switch (type) {
                case DatePullElement.TYPE_ITEM:
                    View viewItem = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.recycler_main_date_sender, viewGroup, false);
                    ViewHolderItem vhItem = new ViewHolderItem(viewItem);
                    vhItem.laySubject = (ViewGroup) viewItem.findViewById(R.id.lay_subject);
                    vhItem.layResponder = (ViewGroup) viewItem.findViewById(R.id.lay_responder);
                    vhItem.layResponderHead = (ViewGroup) viewItem.findViewById(R.id.lay_responder_head);
                    vhItem.txNickname = (TextView) viewItem.findViewById(R.id.tx_nickname);
                    vhItem.txTime = (TextView) viewItem.findViewById(R.id.tx_time);
                    vhItem.txLocation = (TextView) viewItem.findViewById(R.id.tx_location);
                    vhItem.txEmptyResponder = (TextView) viewItem.findViewById(R.id.tx_empty_responder);
                    vhItem.txNickname = (TextView) viewItem.findViewById(R.id.tx_nickname);
                    vhItem.txResponderCount = (TextView) viewItem.findViewById(R.id.tx_responder_count);
                    vhItem.btnUp = (Button) viewItem.findViewById(R.id.btn_up);
                    vhItem.btnUp.setOnClickListener(vhItem);
                    vhItem.imgAvatar = (ImageView) viewItem.findViewById(R.id.img_avatar);
                    vhItem.layAvatar = viewItem.findViewById(R.id.lay_avatar);
                    vhItem.layAvatar.setOnClickListener(onAvatarClickListener);
                    vhItem.layGift = viewItem.findViewById(R.id.lay_gift);
                    vhItem.imgGift = (ImageView) viewItem.findViewById(R.id.img_gift);
                    vhItem.txGiftValue = (TextView) viewItem.findViewById(R.id.tx_gift_value);
                    return vhItem;
                case DatePullElement.TYPE_LOAD:
                    View viewLoad = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.frame_recycler_load, viewGroup, false);
                    return new ViewHolderLoad(viewLoad);
                default:
                    throw new IllegalArgumentException("MainDateLayout error type :" + type);
            }
        }

        private OnClickListener onAvatarClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (v.getTag() != null) {
                    long userId = (long) v.getTag();
                    Intent intent = new Intent(v.getContext(), ProfileInfoActivity.class);
                    intent.putExtra(ProfileInfoActivity.EXTRA_SHOWN_USER_ID, userId);
                    v.getContext().startActivity(intent);
                }
            }
        };

        @Override
        public void onBindViewHolder(final ViewHolder viewHolder, final int position) {
            final DatePullElement de = datePullElements.get(position);
            switch (de.type) {
                case DatePullElement.TYPE_ITEM:
                    final DatePull datePull = (DatePull) de.element;
                    ViewHolderItem vhItem = (ViewHolderItem) viewHolder;
                    Glide.with(vhItem.itemView.getContext()).load(datePull.CreatedUser.head_img_url).placeholder(R.mipmap.common_avatar_c_170)
                            .bitmapTransform(App.i().getCropCircleTransformation()).into(vhItem.imgAvatar);

                    vhItem.txNickname.setText(datePull.CreatedUser.nickname);
                    vhItem.laySubject.removeAllViewsInLayout();
                    for (int j = 0; j < datePull.subject_type.length; j++) {
                        vhItem.laySubject.addView(makeTagView(vhItem.itemView.getContext(), datePull.subject_type[j]));
                    }

                    String date_from = DateUtil.convert(datePull.date_from, DateUtil.yyyy_MM_dd_HH_mm_ss, DateUtil.yyyy_MM_dd_HH_mm);
                    vhItem.txTime.setText(date_from);
                    vhItem.txLocation.setText(!TextUtils.isEmpty(datePull.address) ? datePull.address : "");

                    vhItem.btnUp.setText(datePull.isSelfBooked ? R.string.date_thing_of_the_past : R.string.date_beautiful_future);
                    vhItem.btnUp.setTextColor(datePull.isSelfBooked ? 0xFFB3B3B3 : 0xFFFFFFFF);
                    vhItem.btnUp.setEnabled(!datePull.isSelfBooked);
                    vhItem.btnUp.setTag(vhItem);

                    vhItem.layAvatar.setTag(datePull.CreatedUser.id);

                    boolean zeroResponder = datePull.book_count == 0;
                    if (zeroResponder) {
                        vhItem.txEmptyResponder.setVisibility(View.VISIBLE);
                        vhItem.layResponder.setVisibility(View.GONE);
                    } else {
                        vhItem.txEmptyResponder.setVisibility(View.GONE);
                        vhItem.layResponder.setVisibility(View.VISIBLE);
                        vhItem.layResponderHead.removeAllViewsInLayout();

                        for (int j = 0; j < datePull.book_user_img.length; j++) {
                            if (j >= 4) break;

                            vhItem.layResponderHead.addView(makeResponderHeadImage(vhItem.itemView.getContext(), datePull.book_user_img[j]));
                        }
                        vhItem.txResponderCount.setText(App.i().getString(R.string.date_responder_count, String.valueOf(datePull.book_count)));
                    }

                    boolean isPublisherPay = datePull.gift != null;
                    vhItem.layGift.setVisibility(isPublisherPay ? View.VISIBLE : View.GONE);
                    if (isPublisherPay) {
                        Glide.with(vhItem.itemView.getContext()).load(datePull.gift.image).into(vhItem.imgGift);
                        vhItem.txGiftValue.setText(vhItem.itemView.getContext().getString(R.string.date_pay_value_2, String.valueOf((int) datePull.gift.price)));
                    }

                    vhItem.itemData = datePull;
                    vhItem.position = position;
                    break;

                case DatePullElement.TYPE_LOAD:
                    ViewHolderLoad vhLoad = (ViewHolderLoad) viewHolder;
                    vhLoad.itemView.setVisibility(((boolean) deLoad.element) ? View.VISIBLE : View.GONE);
                    break;
            }
        }

        private TextView makeTagView(Context context, String text) {
            TextView txSubject = new TextView(context);
            txSubject.setLayoutParams(lpSubject);
            txSubject.setTextColor(0xFFFFFFFF);
            txSubject.setTextSize(13);
            txSubject.setText(text);
            txSubject.setGravity(Gravity.CENTER);
            txSubject.setBackgroundResource(R.drawable.date_shape_subject);
            return txSubject;
        }

        private ImageView makeResponderHeadImage(Context context, String url) {
            ImageView imgResponderHead = new ImageView(context);
            imgResponderHead.setLayoutParams(lpResponderHead);
            imgResponderHead.setPadding(0, 0, d5, 0);
            Glide.with(context).load(url).placeholder(R.mipmap.common_avatar_c_60).bitmapTransform(App.i().getCropCircleTransformation()).into(imgResponderHead);
            return imgResponderHead;
        }

        private void requestOrderBook(final ViewHolderItem viewHolder, long oid, final long gift_id) {
            final LoadingDialog dlgLoading = new LoadingDialog.Builder(viewHolder.itemView.getContext()).create();
            dlgLoading.show();
            PnwHttpManager.Order.book(((BaseActivity) viewHolder.itemView.getContext()).TAG, oid, gift_id, new PnwOkCallbackAdapter<HttpResp>() {
                @Override
                public void onResponse(HttpResp response, boolean fresh) {
                    super.onResponse(response, fresh);
                    dlgLoading.dismiss();
                    if (response.errcode == C.http.RESULT_SUCCESS) {
                        viewHolder.itemData.isSelfBooked = true;
                        viewHolder.itemData.book_count++;

                        String[] mModify = new String[viewHolder.itemData.book_count];
                        mModify[viewHolder.itemData.book_count - 1] = App.i().getUser().getHead_img_url();
                        if (viewHolder.itemData.book_user_img != null && viewHolder.itemData.book_user_img.length > 0) {
                            for (int i = 0; i < viewHolder.itemData.book_user_img.length; i++) {
                                mModify[i] = viewHolder.itemData.book_user_img[i];
                            }
                        }
                        viewHolder.itemData.book_user_img = mModify;

                        final com.paishen.peiniwan.database.User other;
                        other = ModelConverter.mergeOrReplace(null, viewHolder.itemData.CreatedUser);
                        EventBus.getDefault().post(new BusEvent(BusEvent.TYPE_BACKGROUND, BusEvent.ACTION_DB_UPDATE_USER, other));

                        notifyItemChanged(viewHolder.position);
                        BaseUtil.showToast(R.string.date_future_come_true);

                    } else if (response.errcode == C.http.RESULT_IDENTITY_VALID_NULL
                            || response.errcode == C.http.RESULT_IDENTITY_VALID_FAIL) {
                        showDatePullDialog(viewHolder.itemView.getContext(), response.errmsg);
                    } else if (fresh && response.errcode != C.http.RESULT_LOGIN_EXPIRE &&
                            response.errcode != C.http.RESULT_LOGIN_OFFLINE) {
                        // RESULT_IDENTITY_VALID_DEALING
                        BaseUtil.showToast(response.errmsg);
                    }
                }

                @Override
                public void onFailure(Request request, Exception e) {
                    super.onFailure(request, e);
                    dlgLoading.dismiss();
                }
            });
        }

        private void showDatePullDialog(Context context, String message) {
            if (dlgDatePull == null) {
                AlertDialog.Builder builder = new AlertDialog.Builder(context);
                builder.setTitle(R.string.tips).setMessage(message).setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dlgDatePull.dismiss();
                    }
                }).setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dlgDatePull.dismiss();
                        EventBus.getDefault().post(new BusEvent(BusEvent.ACTION_TO_MAIN_PROFILE_AUTH));
                    }
                });
                dlgDatePull = builder.create();
            }
            dlgDatePull.show();
        }
    }
}
